package io.hellsinger.vortex.data.repository

import android.os.Environment
import io.hellsinger.filesystem.attribute.PathGroup
import io.hellsinger.filesystem.attribute.PathUser
import io.hellsinger.filesystem.directory.DirectoryEntry
import io.hellsinger.filesystem.linux.attribute.getLinuxGroup
import io.hellsinger.filesystem.linux.attribute.getLinuxUser
import io.hellsinger.filesystem.linux.directory.asLinuxDirectory
import io.hellsinger.filesystem.linux.directory.defaultWalker
import io.hellsinger.filesystem.linux.file.asLinuxFile
import io.hellsinger.filesystem.linux.operation.access
import io.hellsinger.filesystem.linux.operation.read
import io.hellsinger.filesystem.linux.resolve
import io.hellsinger.filesystem.path.Path
import io.hellsinger.vortex.data.asPath
import io.hellsinger.vortex.domain.model.Transition
import io.hellsinger.vortex.domain.repository.StorageRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

class AndroidStorageRepository : StorageRepository {
    private val pending = MutableStateFlow(mutableListOf<Transition>())

    override suspend fun addPendingTransition(transition: Transition) {
        val current = pending.value
        current.add(transition)
        pending.emit(current)
    }

    override suspend fun removePending(transition: Transition) {
        val current = pending.value
        current.remove(transition)
        pending.emit(current)
    }

    override fun getPendingTransitions(): StateFlow<List<Transition>> = pending

    @Throws(IllegalArgumentException::class)
    override suspend fun getEntries(path: Path): Flow<DirectoryEntry<Path>> = path.asLinuxDirectory().defaultWalker()

    override suspend fun getBytes(
        path: Path,
        flags: Int,
    ): Flow<Byte> = path.asLinuxFile().read()

    override suspend fun check(
        path: Path,
        flags: Int,
    ): Int = path.access(flags)

    override suspend fun getUser(id: Int): PathUser = getLinuxUser(id)

    override suspend fun getGroup(id: Int): PathGroup = getLinuxGroup(id)

    companion object {
        val EXTERNAL_STORAGE_PATH = Environment.getExternalStorageDirectory().asPath()
        val OBB_DIRECTORY_PATH = EXTERNAL_STORAGE_PATH.resolve("Android/obb")
        val DATA_DIRECTORY_PATH = EXTERNAL_STORAGE_PATH.resolve("Android/data")
    }
}
